#include "mpicker.h"

#include <QWidget>
#include <QGraphicsSceneMouseEvent>
#include <iostream>

#include "mutil.h"

MPicker::MPicker(QObject *parent) :
    QGraphicsScene(parent)
{
    setSceneRect(0, 0, 700, 250);
    memset(boxes, 0, sizeof(boxes));

    for (int i = 0; i < 15; ++i)
        for (int j = 0; j < (i >= 13 ? 1 : 4); ++j)
        {
            boxes[i][j] = new MBox();
            addItem(boxes[i][j]);
            auto p = new MCard();
            p->id = i;
            boxes[i][j]->setCard(p);

            boxes[i][j]->setPos(OFFSET_X + i * STEP_X, OFFSET_Y + j * STEP_Y);
        }
    s = new MSelector();
    addItem(s);
    s->setPos(0, 0);
    resetSelection();
    connect(s, SIGNAL(newSelection(int,int,int,int)), this, SLOT(workSelection(int,int,int,int)));
    connect(s, SIGNAL(endSelection()), this, SLOT(releaseSelection()));
    connect(s, SIGNAL(moveOver(int,int)), this, SLOT(checkOver(int,int)));

    you = new MTextBox(MUtil::getStr("text_you"), 100, 70);
    prev = new MTextBox(MUtil::getStr("text_prev"), 100, 70);
    next = new MTextBox(MUtil::getStr("text_next"), 100, 70);
    evilmode = false;
}

void MPicker::updateBoxes(MGame *game)
{
    if (game->getState() == MGame::TO_CHOOSE_EVIL)
    {
        evilmode = true;
        for (int i = 0; i < 15; ++i)
            for (int j = 0; j < 4; ++j)
                if (boxes[i][j])
                    boxes[i][j]->setColorVisible(false);
        addItem(prev);
        addItem(you);
        addItem(next);
        prev->setPos(220 - prev->width() / 2, 50);
        you->setPos(350 - you->width() / 2, 130);
        next->setPos(480 - next->width() / 2, 50);
        update();
        return;
    }
    if (evilmode)
    {
        removeItem(prev);
        removeItem(you);
        removeItem(next);
    }
    evilmode = false;

    for (int i = 0; i < 15; ++i)
    {
        MCard c;
        c.id = i;
        int k = game->getPlayerMaxRemain(game->getTurn(), c);
        int o = game->getOutRemain(c);
        if (game->getTurn() == MGame::YOU)
            o += k;
        else
            o = k;
        for (int j = 0; j < 4; ++j)
            if (boxes[i][j])
            {
                if (j < k)
                {
                    boxes[i][j]->setColorVisible(true);
                    boxes[i][j]->setColorActive(true);
                }
                else if (j < o)
                {
                    boxes[i][j]->setColorVisible(true);
                    boxes[i][j]->setColorActive(false);
                }
                else
                {
                    boxes[i][j]->setColorVisible(false);
                    boxes[i][j]->setColorActive(false);
                }
                boxes[i][j]->setColorSelected(selected[i][j]);
            }

    }
    update();
}

std::multiset<MCard> MPicker::getSelected()
{
    std::multiset<MCard> ret;
    ret.clear();

    for (int i = 0; i < 15; ++i)
        for (int j = 0; j < 4; ++j)
            if (selected[i][j])
                ret.insert(boxes[i][j]->getCard());
    return ret;
}

void MPicker::setParentWidget(QWidget *w)
{
    parent_widget = w;
}

void MPicker::workSelection(int l, int u, int r, int d)
{
    for (int i = 0; i < 15; ++i)
        for (int j = 0; j < 4; ++j)
            if (boxes[i][j] && boxes[i][j]->active)
            {
                int x1 = OFFSET_X + i * STEP_X;
                int x2 = x1 + MBox::SIZE;
                int y1 = OFFSET_Y + j * STEP_Y;
                int y2 = y1 + MBox::SIZE;

                if (x1 > r || x2 < l || y1 > d || y2 < u)
                    boxes[i][j]->setColorSelected(selected[i][j]);
                else
                    boxes[i][j]->setColorSelected(!selected[i][j]);
            }

    update();
}

void MPicker::releaseSelection()
{
    if (evilmode)
    {
        if (prev->mouse_over)
        {
            emit evilSelected(MGame::PREV);
            evilmode = false;
        }
        else if (you->mouse_over)
        {
            emit evilSelected(MGame::YOU);
            evilmode = false;
        }
        else if (next->mouse_over)
        {
            emit evilSelected(MGame::NEXT);
            evilmode = false;
        }
    }
    for (int i = 0; i < 15; ++i)
        for (int j = 0; j < 4; ++j)
            if (boxes[i][j])
                selected[i][j] = boxes[i][j]->selected;
}

void MPicker::resetSelection()
{
    memset(selected, 0, sizeof(selected));
}

void MPicker::checkOver(int x, int y)
{

    QPoint p = parent_widget->mapFromGlobal(QPoint(x, y));
    x = p.x();
    y = p.y();

    if (evilmode)
    {
        prev->setMouseOver(
                    x >= prev->pos().x() && x <= prev->pos().x() + prev->width() &&
                    y >= prev->pos().y() && y <= prev->pos().y() + prev->height()
                    );

        you->setMouseOver(
                    x >= you->pos().x() && x <= you->pos().x() + you->width() &&
                    y >= you->pos().y() && y <= you->pos().y() + you->height()
                    );

        next->setMouseOver(
                    x >= next->pos().x() && x <= next->pos().x() + next->width() &&
                    y >= next->pos().y() && y <= next->pos().y() + next->height()
                    );
        update();
    }
}
